using System;
using UnityEngine;

namespace GenerativeAgents.Core
{
    /// <summary>
    /// 分数计算器
    /// 负责计算记忆节点的各种评分指标
    /// </summary>
    public class ScoreCalculator
    {
        private float temporalDecayRate = 0.01f;
        private float accessFrequencyWeight = 0.1f;
        private float semanticSimilarityThreshold = 0.3f;
        
        public ScoreCalculator()
        {
            // 可以从配置加载参数
        }
        
        /// <summary>
        /// 计算综合分数
        /// </summary>
        public float CalculateCompositeScore(MemoryNode memory, ProcessedQuery query, float recencyWeight, float importanceWeight, float relevanceWeight)
        {
            try
            {
                // 计算三个维度的分数
                var recencyScore = CalculateRecencyScore(memory);
                var importanceScore = CalculateImportanceScore(memory);
                var relevanceScore = CalculateRelevanceScore(memory, query);
                
                // 归一化分数
                var normalizedRecency = NormalizeScore(recencyScore, 0f, 1f);
                var normalizedImportance = NormalizeScore(importanceScore, 0f, 1f);
                var normalizedRelevance = NormalizeScore(relevanceScore, 0f, 1f);
                
                // 加权组合
                var compositeScore = normalizedRecency * recencyWeight + 
                                   normalizedImportance * importanceWeight + 
                                   normalizedRelevance * relevanceWeight;
                
                // 应用额外的加成因子
                compositeScore += CalculateAccessFrequencyBonus(memory);
                compositeScore += CalculateContextualBonus(memory, query);
                
                return Mathf.Clamp01(compositeScore);
            }
            catch (Exception ex)
            {
                Debug.LogError($"[ScoreCalculator] Error calculating composite score: {ex.Message}");
                return 0f;
            }
        }
        
        /// <summary>
        /// 计算新近度分数
        /// </summary>
        public float CalculateRecencyScore(MemoryNode memory)
        {
            try
            {
                var timeSinceLastAccess = (DateTime.Now - memory.lastAccessTime).TotalHours;
                var timeSinceCreation = (DateTime.Now - memory.createdTime).TotalHours;
                
                // 使用最近访问时间和创建时间的加权平均
                var effectiveTime = (timeSinceLastAccess * 0.7) + (timeSinceCreation * 0.3);
                
                // 指数衰减函数
                var recencyScore = Mathf.Exp(-(float)effectiveTime * temporalDecayRate);
                
                // 访问频率加成
                if (memory.accessCount > 1)
                {
                    var accessBonus = Mathf.Log(memory.accessCount) * 0.05f;
                    recencyScore += accessBonus;
                }
                
                return Mathf.Clamp01(recencyScore);
            }
            catch (Exception ex)
            {
                Debug.LogError($"[ScoreCalculator] Error calculating recency score: {ex.Message}");
                return 0f;
            }
        }
        
        /// <summary>
        /// 计算重要性分数
        /// </summary>
        public float CalculateImportanceScore(MemoryNode memory)
        {
            try
            {
                // 基础重要性分数（1-10映射到0-1）
                var baseImportance = memory.poignancy / 10f;
                
                // 记忆类型加成
                var typeBonus = GetMemoryTypeBonus(memory.type);
                
                // 参与者数量加成
                var participantBonus = 0f;
                if (memory.participants != null && memory.participants.Count > 1)
                {
                    participantBonus = Mathf.Min(0.2f, memory.participants.Count * 0.05f);
                }
                
                // 关联记忆数量加成
                var associationBonus = 0f;
                if (memory.relatedNodeIds != null && memory.relatedNodeIds.Count > 0)
                {
                    associationBonus = Mathf.Min(0.15f, memory.relatedNodeIds.Count * 0.03f);
                }
                
                var totalImportance = baseImportance + typeBonus + participantBonus + associationBonus;
                return Mathf.Clamp01(totalImportance);
            }
            catch (Exception ex)
            {
                Debug.LogError($"[ScoreCalculator] Error calculating importance score: {ex.Message}");
                return memory.poignancy / 10f; // 返回基础分数
            }
        }
        
        /// <summary>
        /// 计算相关性分数
        /// </summary>
        public float CalculateRelevanceScore(MemoryNode memory, ProcessedQuery query)
        {
            try
            {
                float relevanceScore = 0f;
                
                // 语义相似度（如果有嵌入向量）
                if (memory.embedding != null && query.embedding != null)
                {
                    var semanticSimilarity = CalculateCosineSimilarity(memory.embedding, query.embedding);
                    relevanceScore += semanticSimilarity * 0.6f;
                }
                
                // 关键词匹配
                var keywordSimilarity = CalculateKeywordSimilarity(memory, query);
                relevanceScore += keywordSimilarity * 0.3f;
                
                // 内容文本匹配
                var textSimilarity = CalculateTextSimilarity(memory.content, query.cleanedQuery);
                relevanceScore += textSimilarity * 0.1f;
                
                // 上下文相关性
                var contextRelevance = CalculateContextRelevance(memory, query);
                relevanceScore += contextRelevance * 0.2f;
                
                return Mathf.Clamp01(relevanceScore);
            }
            catch (Exception ex)
            {
                Debug.LogError($"[ScoreCalculator] Error calculating relevance score: {ex.Message}");
                return 0f;
            }
        }
        
        /// <summary>
        /// 计算访问频率加成
        /// </summary>
        private float CalculateAccessFrequencyBonus(MemoryNode memory)
        {
            if (memory.accessCount <= 1) return 0f;
            
            // 对数缩放访问频率加成
            var frequencyBonus = Mathf.Log(memory.accessCount) * accessFrequencyWeight;
            return Mathf.Min(0.2f, frequencyBonus); // 最大20%加成
        }
        
        /// <summary>
        /// 计算上下文加成
        /// </summary>
        private float CalculateContextualBonus(MemoryNode memory, ProcessedQuery query)
        {
            float bonus = 0f;
            
            // 查询意图与记忆类型的匹配
            switch (query.intent)
            {
                case QueryIntent.Social:
                    if (memory.type == MemoryType.Chat || memory.type == MemoryType.Event)
                        bonus += 0.1f;
                    break;
                    
                case QueryIntent.Planning:
                    if (memory.type == MemoryType.Plan || memory.type == MemoryType.Knowledge)
                        bonus += 0.1f;
                    break;
                    
                case QueryIntent.Reflection:
                    if (memory.type == MemoryType.Thought || memory.type == MemoryType.Reflection)
                        bonus += 0.15f;
                    break;
                    
                case QueryIntent.Recall:
                    if (memory.type == MemoryType.Event || memory.type == MemoryType.Observation)
                        bonus += 0.1f;
                    break;
            }
            
            // 实体匹配加成
            if (query.entities != null && memory.participants != null)
            {
                var entityMatches = query.entities.Intersect(memory.participants).Count();
                if (entityMatches > 0)
                {
                    bonus += entityMatches * 0.05f;
                }
            }
            
            return Mathf.Min(0.25f, bonus); // 最大25%加成
        }
        
        /// <summary>
        /// 获取记忆类型加成
        /// </summary>
        private float GetMemoryTypeBonus(MemoryType memoryType)
        {
            switch (memoryType)
            {
                case MemoryType.Reflection:
                case MemoryType.Thought:
                    return 0.15f; // 反思和思想记忆更重要
                    
                case MemoryType.Plan:
                    return 0.1f; // 计划记忆较重要
                    
                case MemoryType.Chat:
                case MemoryType.Event:
                    return 0.05f; // 对话和事件记忆中等重要
                    
                case MemoryType.Knowledge:
                    return 0.08f; // 知识记忆较重要
                    
                default:
                    return 0f;
            }
        }
        
        /// <summary>
        /// 计算余弦相似度
        /// </summary>
        private float CalculateCosineSimilarity(float[] vector1, float[] vector2)
        {
            if (vector1 == null || vector2 == null || vector1.Length != vector2.Length)
                return 0f;
            
            float dotProduct = 0f;
            float norm1 = 0f;
            float norm2 = 0f;
            
            for (int i = 0; i < vector1.Length; i++)
            {
                dotProduct += vector1[i] * vector2[i];
                norm1 += vector1[i] * vector1[i];
                norm2 += vector2[i] * vector2[i];
            }
            
            if (norm1 == 0f || norm2 == 0f)
                return 0f;
            
            return dotProduct / (Mathf.Sqrt(norm1) * Mathf.Sqrt(norm2));
        }
        
        /// <summary>
        /// 计算关键词相似度
        /// </summary>
        private float CalculateKeywordSimilarity(MemoryNode memory, ProcessedQuery query)
        {
            if (memory.keywords == null || memory.keywords.Count == 0 || 
                query.keywords == null || query.keywords.Count == 0)
                return 0f;
            
            var memoryKeywords = memory.keywords.Select(k => k.ToLower()).ToHashSet();
            var queryKeywords = query.keywords.Select(k => k.ToLower()).ToHashSet();
            
            // 计算交集和并集
            var intersection = memoryKeywords.Intersect(queryKeywords).Count();
            var union = memoryKeywords.Union(queryKeywords).Count();
            
            if (union == 0) return 0f;
            
            // Jaccard相似度
            var jaccardSimilarity = (float)intersection / union;
            
            // 额外的部分匹配检查
            var partialMatches = 0f;
            foreach (var memKeyword in memoryKeywords)
            {
                foreach (var queryKeyword in queryKeywords)
                {
                    if (memKeyword.Contains(queryKeyword) || queryKeyword.Contains(memKeyword))
                    {
                        partialMatches += 0.5f;
                    }
                }
            }
            
            var partialSimilarity = partialMatches / Math.Max(memoryKeywords.Count, queryKeywords.Count);
            
            return Mathf.Max(jaccardSimilarity, partialSimilarity * 0.3f);
        }
        
        /// <summary>
        /// 计算文本相似度
        /// </summary>
        private float CalculateTextSimilarity(string memoryContent, string queryText)
        {
            if (string.IsNullOrEmpty(memoryContent) || string.IsNullOrEmpty(queryText))
                return 0f;
            
            var memoryWords = memoryContent.ToLower().Split(new char[] { ' ', '.', ',', '!', '?' }, StringSplitOptions.RemoveEmptyEntries);
            var queryWords = queryText.ToLower().Split(new char[] { ' ', '.', ',', '!', '?' }, StringSplitOptions.RemoveEmptyEntries);
            
            if (memoryWords.Length == 0 || queryWords.Length == 0)
                return 0f;
            
            var memoryWordSet = memoryWords.ToHashSet();
            var queryWordSet = queryWords.ToHashSet();
            
            var commonWords = memoryWordSet.Intersect(queryWordSet).Count();
            var totalWords = Math.Max(memoryWordSet.Count, queryWordSet.Count);
            
            return (float)commonWords / totalWords;
        }
        
        /// <summary>
        /// 计算上下文相关性
        /// </summary>
        private float CalculateContextRelevance(MemoryNode memory, ProcessedQuery query)
        {
            float relevance = 0f;
            
            // 查询上下文与记忆类型的匹配
            switch (query.context)
            {
                case QueryContext.Conversation:
                    if (memory.type == MemoryType.Chat || memory.type == MemoryType.Event)
                        relevance += 0.3f;
                    break;
                    
                case QueryContext.Planning:
                    if (memory.type == MemoryType.Plan || memory.type == MemoryType.Event)
                        relevance += 0.3f;
                    break;
                    
                case QueryContext.Reflection:
                    if (memory.type == MemoryType.Thought || memory.type == MemoryType.Reflection)
                        relevance += 0.4f;
                    break;
                    
                case QueryContext.Social:
                    if (memory.participants != null && memory.participants.Count > 1)
                        relevance += 0.2f;
                    break;
                    
                case QueryContext.Navigation:
                    if (!string.IsNullOrEmpty(memory.locationName))
                        relevance += 0.2f;
                    break;
            }
            
            // 时间相关性（对于时间敏感的查询）
            if (query.intent == QueryIntent.Time)
            {
                var timeDiff = Math.Abs((DateTime.Now - memory.createdTime).TotalHours);
                if (timeDiff < 24) // 24小时内的记忆更相关
                {
                    relevance += 0.2f * (1f - (float)timeDiff / 24f);
                }
            }
            
            return Mathf.Clamp01(relevance);
        }
        
        /// <summary>
        /// 归一化分数
        /// </summary>
        private float NormalizeScore(float score, float min, float max)
        {
            if (max <= min) return 0f;
            return Mathf.Clamp01((score - min) / (max - min));
        }
        
        /// <summary>
        /// 设置计算参数
        /// </summary>
        public void SetCalculationParameters(float decayRate, float frequencyWeight, float similarityThreshold)
        {
            temporalDecayRate = decayRate;
            accessFrequencyWeight = frequencyWeight;
            semanticSimilarityThreshold = similarityThreshold;
        }
        
        /// <summary>
        /// 获取分数详细信息（用于调试）
        /// </summary>
        public ScoreDetails GetScoreDetails(MemoryNode memory, ProcessedQuery query, float recencyWeight, float importanceWeight, float relevanceWeight)
        {
            return new ScoreDetails
            {
                recencyScore = CalculateRecencyScore(memory),
                importanceScore = CalculateImportanceScore(memory),
                relevanceScore = CalculateRelevanceScore(memory, query),
                accessFrequencyBonus = CalculateAccessFrequencyBonus(memory),
                contextualBonus = CalculateContextualBonus(memory, query),
                compositeScore = CalculateCompositeScore(memory, query, recencyWeight, importanceWeight, relevanceWeight)
            };
        }
    }
    
    /// <summary>
    /// 分数详细信息结构
    /// </summary>
    public struct ScoreDetails
    {
        public float recencyScore;
        public float importanceScore;
        public float relevanceScore;
        public float accessFrequencyBonus;
        public float contextualBonus;
        public float compositeScore;
        
        public override string ToString()
        {
            return $"Recency: {recencyScore:F3}, Importance: {importanceScore:F3}, Relevance: {relevanceScore:F3}, " +
                   $"Frequency Bonus: {accessFrequencyBonus:F3}, Context Bonus: {contextualBonus:F3}, " +
                   $"Composite: {compositeScore:F3}";
        }
    }
}